package com.xuhuan.demo.convert;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.io.File;

/**
 * @author huan.xu
 * @date 2021/11/23 18:29
 * @description jacob实现word转pdf
 * <p>
 * 使用jacob注意：
 *      1.引入jar包：src/main/resources/lib/jacob.jar
 *      2.src/main/resources/lib/jacob-1.18.zip中包含了jacob的dll文件和jar，这个根据操作系统的情况把dll文件放入jdk的bin目录下
 *      3.如果是maven项目，那么就引入依赖，具体步骤如下：
 *          1）按照路径放入src/main/resources/lib/jacob.jar
 *          2）配置maven依赖
 *              <dependency>
 *              <groupId>com.jacob</groupId>
 *              <artifactId>jacob</artifactId>
 *              <version>1.18</version>
 *              <scope>system</scope>
 *              <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>//这个为本地jar路径
 *              </dependency>
 *      4.jacob无法在linux下运行
 */
@Slf4j
public class Word2PdfJacobUtil {

    /**
     * 私有构造器
     */
    private Word2PdfJacobUtil() {
    }

    /**
     * wore转pdf
     * @param wordFilePath word文件路径
     * @param pdfFilePath pdf文件路径
     * @throws Exception
     */
    public static void word2pdf(String wordFilePath, String pdfFilePath) throws Exception {
        ActiveXComponent app = null;

        File wordFile = new File(wordFilePath);
        if (!wordFile.exists()) {
            log.error("word转pdf失败,word文件[{}]不存在", wordFilePath);
            throw new RuntimeException("word转pdf失败,word文件不存在");
        }

        try {
            //开始时间
            long start = System.currentTimeMillis();
            // 打开word
            app = new ActiveXComponent("Word.Application");
            // 设置word不可见,很多博客下面这里都写了这一句话，其实是没有必要的，因为默认就是不可见的，如果设置可见就是会打开一个word文档，对于转化为pdf明显是没有必要的
            //app.setProperty("Visible", false);
            // 获得word中所有打开的文档
            Dispatch documents = app.getProperty("Documents").toDispatch();
            log.info("打开word文件:[{}] ", wordFilePath);
            // 打开文档
            Dispatch document = Dispatch.call(documents, "Open", wordFilePath, false, true).toDispatch();
            // 如果文件存在的话，不会覆盖，会直接报错，所以我们需要判断文件是否存在
            File pdfFile = new File(pdfFilePath);
            if (pdfFile.exists()) {
                pdfFile.delete();
            }
            log.info("另存pdf文件为:[{}] ", pdfFilePath);
            // 另存为，将文档保存为pdf，其中word保存为pdf的格式宏的值是17
            Dispatch.call(document, "SaveAs", pdfFilePath, 17);
            // 关闭文档
            Dispatch.call(document, "Close", false);
            // 结束时间
            long end = System.currentTimeMillis();
            log.info("转换成功，用时(秒)：[{}]", (end - start) / 1000);
        } catch (Exception e) {
            log.error("word转pdf失败,word文件路径[{}],pdf文件路径[{}]",
                    wordFilePath,
                    pdfFilePath);
            log.error("错误信息：{}", ExceptionUtils.getFullStackTrace(e));
            throw new RuntimeException("word转pdf出错");
        } finally {
            // 关闭office
            app.invoke("Quit", 0);
        }
    }

    public static void main(String args[]) throws Exception{
        word2pdf("C:\\Users\\huan.xu\\Downloads\\1.doc","C:\\Users\\huan.xu\\Downloads\\1.pdf");
    }
}
